package com.chuxing.system.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuxing.config.PermissionsState;
import com.chuxing.config.SecurityRole;
import com.chuxing.domain.ClassInfo;
import com.chuxing.domain.DTO.TClassListMembersDTO;
import com.chuxing.domain.TClassMembers;
import com.chuxing.domain.User;
import com.chuxing.domain.VO.PageResultVO;
import com.chuxing.exception.GenericException;
import com.chuxing.exception.UnauthorizedException;
import com.chuxing.security.mapper.UserMapper;
import com.chuxing.system.mapper.ClassinfoMapper;
import com.chuxing.system.mapper.TClassMembersMapper;
import com.chuxing.system.mapper.TGroupMembersMapper;
import com.chuxing.system.service.ITClassMembersService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/**
 * 班级成员信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-12-14
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class TClassMembersServiceImpl extends ServiceImpl<TClassMembersMapper, TClassMembers> implements ITClassMembersService
{
    private final TClassMembersMapper tClassMembersMapper;
    private final UserMapper userMapper;
    private final TGroupMembersMapper tGroupMembersMapper;
    private final ClassinfoMapper classinfoMapper;

    /**
     * 查询班级成员信息
     * 
     * @param id 班级成员信息主键
     * @return 班级成员信息
     */
    @Override
    @Cacheable(value = "tClassMembersCache", key = "'id'+#id")
    public TClassMembers selectTClassById(Long id)
    {
        return tClassMembersMapper.selectTClassById(id);
    }

    /**
     * 查询班级成员信息列表
     * 
     * @param tClassListMembersDTO 班级成员信息
     * @return 班级成员信息
     */
    @Override
    @Cacheable(value = "tClassMembersCache", key = "#tClassListMembersDTO")
    public PageResultVO selectTClassList(TClassListMembersDTO tClassListMembersDTO)
    {
        if(tClassListMembersDTO.getClassID()==null){
            if(!StpUtil.hasRole(SecurityRole.ROLE_ADMIN)){
                throw new GenericException(PermissionsState.PERMISSION_NOT_ENOUGH);
            }
        }
        // 验证分页参数
        int pageNum = Math.max(1, tClassListMembersDTO.getPageNum());
        int pageSize = Math.max(1, tClassListMembersDTO.getPageSize());
        // 启用分页查询
        PageHelper.startPage(pageNum, pageSize);
        try {
            try (Page<TClassMembers> page = tClassMembersMapper.selectTClassList(tClassListMembersDTO)) {
                List<TClassMembers> result = page.getResult();
                boolean isSelf=true;
                String studentId = StpUtil.getLoginIdAsString();
                for (TClassMembers tClassMembers : result) {
                    if (tClassMembers.getStudentId().equals(studentId)) {
                        isSelf = false;
                        break;
                    }
                }
                if(!StpUtil.hasRole(SecurityRole.ROLE_ADMIN)){
                    if(isSelf) throw new UnauthorizedException(PermissionsState.PERMISSION_NOT_ENOUGH);
                }
                // 构造并返回分页结果对象
                return new PageResultVO(page.getTotal(), result);
            }
        } catch (Exception e) {
            // 抛出通用异常，不暴露具体错误信息
            e.printStackTrace();
            throw new GenericException("系统内部错误");
        } finally {
            // 确保分页查询结束
            PageHelper.clearPage();
        }
    }

    /**
     * 新增班级成员信息
     * 
     * @param tClassMembers 班级成员信息
     * @return 结果
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "tClassMembersCache", allEntries = true),
            @CacheEvict(value = "userInfo", allEntries = true),
            @CacheEvict(value = "tGroupMembersList", allEntries = true)
    })
    public int insertTClass(TClassMembers tClassMembers)
    {
        //查询对应学号的账号是否存在
        User user = userMapper.selectByStudentId(tClassMembers.getStudentId());
        //如果账号存在，则修改账号信息
        if(user != null){
            user.setClassID(tClassMembers.getClassID());
            //更新账号信息
            userMapper.updateByStudentId(user);
        }
        //查询对应学号和班级是否存在
        List<TClassMembers> tClassMembers1 = tClassMembersMapper.selectTClassByStudentId(tClassMembers.getStudentId());
        for (TClassMembers aClass : tClassMembers1) {
            if(aClass.getClassID().equals(tClassMembers.getClassID())){
                //如果存在，则删除旧记录
                tClassMembersMapper.deleteTClassById(aClass.getId());
            }
        }
        // 插入班级成员信息
        tClassMembers.setCreateTime(LocalDateTime.now());
        tClassMembers.setUpdateTime(LocalDateTime.now());
        return tClassMembersMapper.insertTClass(tClassMembers);
    }

    /**
     * 修改班级成员信息
     * 
     * @param tClassMembers 班级成员信息
     * @return 结果
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "tClassMembersCache", allEntries = true),
            @CacheEvict(value = "userInfo", allEntries = true),
            @CacheEvict(value = "tGroupMembersList", allEntries = true)
    })
    public int updateTClass(TClassMembers tClassMembers)
    {
        //查询对应学号的账号是否存在
        User user = userMapper.selectByStudentId(tClassMembers.getStudentId());
        //如果账号存在，则修改账号信息
        if(user != null){
            user.setClassID(tClassMembers.getClassID());
            //更新账号信息
            userMapper.updateByStudentId(user);
        }
        //查询修改前的信息
        TClassMembers OrigintClassMembers = tClassMembersMapper.selectTClassById(tClassMembers.getId());

        //判断当前学生是否已加入小组，如果加入小组，则修改失败
        if(!OrigintClassMembers.getClassID().equals(tClassMembers.getClassID())){
            Long count = tGroupMembersMapper.countByStudentAndClass(OrigintClassMembers.getStudentId(), OrigintClassMembers.getClassID());
            if(count>0){
                throw new GenericException("该学生已加入小组，无法修改班级!");
            }
        }
        //查询对应学号和班级是否存在
        TClassMembers NowtClassMembers = tClassMembersMapper.selectTclassMembersByStudentIdAndTClassInfo(tClassMembers.getStudentId(), tClassMembers.getClassID());
        //如何id相同，则不删除旧记录
        if(NowtClassMembers!=null){
            if(!NowtClassMembers.getId().equals(tClassMembers.getId())){
                //如果存在，则删除旧记录
                tClassMembersMapper.deleteTClassById(NowtClassMembers.getId());
            }
        }
        tClassMembers.setUpdateTime(LocalDateTime.now());
        return tClassMembersMapper.updateTClass(tClassMembers);
    }

    /**
     * 批量删除班级成员信息
     * 
     * @param ids 需要删除的班级成员信息主键
     * @return 结果
     */
    @Override
    @Caching(evict = {
            @CacheEvict(value = "tClassMembersCache", allEntries = true),
            @CacheEvict(value = "userInfo", allEntries = true),
            @CacheEvict(value = "tGroupMembersList", allEntries = true)
    })
    public int deleteTClassByIds(Long[] ids)
    {
        for (Long id : ids) {
            TClassMembers tClassMembers = tClassMembersMapper.selectTClassById(id);
            //查询对应学号的账号是否存在
            User user = userMapper.selectByStudentId(tClassMembers.getStudentId());
            //如果账号存在，则修改账号信息
            if(user != null){
                user.setClassID(null);
                //更新账号信息
                userMapper.updateByStudentId(user);
            }
            //判断该账号是否加入小组，已加入则无法删除
            Long count = tGroupMembersMapper.countByStudentAndClass(tClassMembers.getStudentId(), tClassMembers.getClassID());
            if(count>0){
                throw new GenericException("该学生已加入小组，无法删除");
            }
        }
        return tClassMembersMapper.deleteTClassByIds(ids);
    }

    @Override
    public void export(HttpServletResponse response, TClassListMembersDTO tClassListMembersDTO) {
        try {
            // 调用服务层方法获取班级成员信息列表
            PageResultVO list = selectTClassList(tClassListMembersDTO);
            // 获取班级成员信息记录列表
            List<TClassMembers> listRecords = list.getRecords();
            // 加载班级成员信息模板文件
            InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("static/班级成员信息.xlsx");
            // 创建Workbook对象用于操作Excel文件
            Workbook workbook  = null;
            // 检查是否成功加载模板文件
            if (resourceAsStream != null) {
                workbook  = new XSSFWorkbook(resourceAsStream);
            }
            //查询所有班级信息
            List<ClassInfo> classInfoList = classinfoMapper.selectClassinfo();
            HashMap<Long, String> classMap = new HashMap<>();
            for (ClassInfo classInfo : classInfoList) {
                classMap.put(classInfo.getId(),classInfo.getClassName());
            }
            // 检查Workbook对象是否创建成功
            if (workbook != null) {
                // 获取第一个Sheet页
                Sheet sheet = workbook.getSheetAt(0); //读取
                // 遍历班级成员信息记录并写入Excel
                for (int i = 0; i < listRecords.size(); i++) {
                    // 创建新行
                    Row row = sheet.createRow(i + 1);
                    int j=0;
                    // 写入学生ID
                    row.createCell(j++).setCellValue(listRecords.get(i).getStudentId());
                    // 写入学生姓名
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuName());
                    // 写入学生性别
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuSex());
                    // 写入班级名称
                    row.createCell(j++).setCellValue(classMap.get(listRecords.get(i).getClassID()));
                    // 写入学生所在院系
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuDepartment());
                    // 写入学生专业
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuSpeciality());
                    // 写入学生班级
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuClass());
                    // 写入学生年级
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuGrade());
                    // 写入学生邮箱
                    row.createCell(j++).setCellValue(listRecords.get(i).getEmail());
                    // 写入学生电话
                    row.createCell(j++).setCellValue(listRecords.get(i).getStuPhone());
                }
                // 将Excel数据写入HTTP响应流
                workbook.write(response.getOutputStream());
                // 关闭Workbook对象
                workbook.close();
                // 关闭输入流
                resourceAsStream.close();
                // 刷新HTTP响应流
                response.getOutputStream().flush();
                // 关闭HTTP响应流
                response.getOutputStream().close();
                log.info("管理员导出班级成员信息列表成功");
            }
        } catch (IOException e) {
            throw new GenericException("导出班级成员信息列表失败");
        }
    }

    @Override
    public TClassMembers selectTclassMembersByStudentIdAndTClassInfo(String studentID, Long classID) {
        return tClassMembersMapper.selectTclassMembersByStudentIdAndTClassInfo(studentID,classID);
    }

}
